package presentation;

import java.awt.Color;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JFrame;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class CustomizedChart extends JFrame {

	private static final long serialVersionUID = 1L;

	List<XYSeries> series;
	final JFreeChart chart;
	final ChartPanel panel;

	public CustomizedChart(String name, double xTickUnit, double yTickUnit, double yLowest, double yHighest){

		series = new ArrayList<XYSeries>();
		chart = createOverlaidChart(name, xTickUnit, yTickUnit, yLowest, yHighest);
		panel = new ChartPanel(chart, true, true, true, true, true);

		panel.setPreferredSize(new Dimension(800, 600));
		add(panel);
	}

	public void addLines(Map<Integer, List<Point>> pointsMap, String seriesName, Color color) {
		Iterator<Entry<Integer, List<Point>>> it = pointsMap.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<Integer, List<Point>> pairs = (Map.Entry<Integer, List<Point>>) it.next();
			List<Point> points = (List<Point>) pairs.getValue();
			addLine(points, seriesName, color);
		}
	}
	
	@SuppressWarnings("deprecation")
	public void addLine(List<Point> Ps, String seriesName, Color color) {

		series.add(new XYSeries(seriesName));
		int lastIndex = series.size() - 1;
		final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
		renderer.setPaint(color);
		XYPlot plot = chart.getXYPlot();
		plot.setDataset(lastIndex, new XYSeriesCollection(series.get(lastIndex)));
		plot.setRenderer(lastIndex, renderer);
		for (int i = 0; i < Ps.size(); i += 2)
			this.series.get(lastIndex).add((double) Ps.get(i).x, Ps.get(i + 1).y);
	}

	@SuppressWarnings("deprecation")
	public void addDots(List<Point> points, String seriesName, Color color) {

		series.add(new XYSeries(seriesName));
		int lastIndex = series.size() - 1;
		final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(false, true);
		renderer.setPaint(color);
		XYPlot plot = chart.getXYPlot();
		plot.setDataset(lastIndex, new XYSeriesCollection(series.get(lastIndex)));
		plot.setRenderer(lastIndex, renderer);

		for (Point point : points) {
			this.series.get(lastIndex).add((double) point.x, point.y);
		}
	}
	
	@SuppressWarnings("deprecation")
	public void addBars(List<Point> points, String seriesName, Color color) {

		series.add(new XYSeries(seriesName));
		int lastIndex = series.size() - 1;
		
		final XYBarRenderer renderer = new XYBarRenderer();
		  renderer.setDrawBarOutline(false);
		  renderer.setShadowVisible(false);
		  renderer.setBaseItemLabelsVisible(true);
		
		renderer.setPaint(color);
		XYPlot plot = chart.getXYPlot();
		plot.setDataset(lastIndex, new XYSeriesCollection(series.get(lastIndex)));
		plot.setRenderer(lastIndex, renderer);

		for (Point point : points) {
			this.series.get(lastIndex).add((double) point.x, point.y);
		}
	}

	private JFreeChart createOverlaidChart(String name, double xTickUnit, double yTickUnit,double yLowest, double yHighest) {
		
		final NumberAxis domainAxis = new NumberAxis("X");
		final ValueAxis rangeAxis = new NumberAxis("Y");
		final XYPlot plot = new XYPlot();
		
		if(yLowest !=0 || yHighest !=0)
		rangeAxis.setRange(yLowest,yHighest);
		
		plot.setDomainAxis(domainAxis);
		plot.setRangeAxis(rangeAxis);

		NumberAxis domain = (NumberAxis) plot.getDomainAxis();
		NumberAxis ordinate = (NumberAxis) plot.getRangeAxis();
		
		if(xTickUnit != 0)
			domain.setTickUnit(new NumberTickUnit(xTickUnit));		
		
		if(yTickUnit != 0)
			ordinate.setTickUnit(new NumberTickUnit(yTickUnit));

		return new JFreeChart(name, JFreeChart.DEFAULT_TITLE_FONT, plot, true);

	}
}